<script setup lang="ts">
import type { RateLimitConfigEntity, RateLimitConfigQueryParams } from '#/api';

import { computed, onMounted, reactive, ref } from 'vue';

import { useVbenVxeGrid } from '@vben/plugins/vxe-table';

import {
  Button,
  Card,
  Col,
  Form,
  FormItem,
  Input,
  InputNumber,
  message,
  Modal,
  Radio,
  RadioGroup,
  Row,
  Select,
  SelectOption,
  Space,
  Switch,
  Tag,
  Textarea,
  Tooltip,
} from 'ant-design-vue';
import {
  CheckCircle,
  Edit,
  Plus,
  RefreshCw,
  Search,
  Settings,
  Trash2,
  XCircle,
} from 'lucide-vue-next';

import {
  batchCreateConfigApi,
  createConfigApi,
  deleteConfigApi,
  getConfigListApi,
  refreshConfigApi,
  updateConfigApi,
  updateConfigEnabledApi,
} from '#/api';

// 搜索参数
const searchParams = reactive<RateLimitConfigQueryParams>({
  configName: undefined,
  configType: undefined,
  enabled: undefined,
  pageNum: 1,
  pageSize: 10,
});

// 配置类型选项
const configTypeOptions = [
  { label: '默认限流', value: 'DEFAULT' },
  { label: 'IP限流', value: 'IP' },
  { label: '用户限流', value: 'USER' },
  { label: '路径限流', value: 'PATH' },
];

// 限流类型选项
const limitTypeOptions = [
  { label: 'IP限流', value: 'IP' },
  { label: '用户限流', value: 'USER' },
  { label: '全局限流', value: 'GLOBAL' },
];

// 弹窗状态
const modalVisible = ref(false);
const modalTitle = ref('新增配置');
const isEdit = ref(false);

// 表单数据
const formData = ref<RateLimitConfigEntity>({
  configName: '',
  configType: 'DEFAULT',
  limitType: 'GLOBAL',
  pathPattern: '',
  windowSeconds: 60,
  maxRequests: 100,
  enabled: true,
  whiteList: '',
  description: '',
});

// 表格配置
const [Grid, gridApi] = useVbenVxeGrid<RateLimitConfigEntity>({
  gridOptions: {
    data: [],
    loading: false,
    pagerConfig: {
      enabled: true,
      currentPage: 1,
      pageSize: 10,
      total: 0,
      pageSizes: [10, 20, 50, 100],
      layouts: [
        'PrevJump',
        'PrevPage',
        'Number',
        'NextPage',
        'NextJump',
        'Sizes',
        'Total',
      ],
    },
    columns: [
      {
        field: 'id',
        title: 'ID',
        width: 80,
        align: 'center',
      },
      {
        field: 'configName',
        title: '配置名称',
        minWidth: 150,
      },
      {
        field: 'configType',
        title: '配置类型',
        width: 120,
        align: 'center',
        slots: { default: 'configType' },
      },
      {
        field: 'limitType',
        title: '限流类型',
        width: 120,
        align: 'center',
        slots: { default: 'limitType' },
      },
      {
        field: 'pathPattern',
        title: '路径模式',
        minWidth: 180,
        slots: { default: 'pathPattern' },
      },
      {
        field: 'windowSeconds',
        title: '时间窗口(秒)',
        width: 130,
        align: 'center',
      },
      {
        field: 'maxRequests',
        title: '最大请求数',
        width: 120,
        align: 'center',
      },
      {
        field: 'enabled',
        title: '状态',
        width: 100,
        align: 'center',
        slots: { default: 'enabled' },
      },
      {
        field: 'whiteList',
        title: 'IP白名单',
        minWidth: 180,
        slots: { default: 'whiteList' },
      },
      {
        field: 'description',
        title: '描述',
        minWidth: 200,
        showOverflow: 'tooltip',
      },
      {
        field: 'action',
        title: '操作',
        width: 200,
        align: 'center',
        fixed: 'right',
        slots: { default: 'action' },
      },
    ],
  },
});

// 获取配置类型标签颜色
function getConfigTypeColor(type: string) {
  const colorMap: Record<string, string> = {
    DEFAULT: 'blue',
    IP: 'green',
    USER: 'orange',
    PATH: 'purple',
  };
  return colorMap[type] || 'default';
}

// 获取限流类型标签颜色
function getLimitTypeColor(type: string) {
  const colorMap: Record<string, string> = {
    IP: 'cyan',
    USER: 'gold',
    GLOBAL: 'magenta',
  };
  return colorMap[type] || 'default';
}

// 获取配置类型标签文本
function getConfigTypeText(type: string) {
  const option = configTypeOptions.find((opt) => opt.value === type);
  return option?.label || type;
}

// 获取限流类型标签文本
function getLimitTypeText(type: string) {
  const option = limitTypeOptions.find((opt) => opt.value === type);
  return option?.label || type;
}

// 解析白名单数组
function getWhiteListArray(whiteList: string): string[] {
  if (!whiteList || !whiteList.trim()) {
    return [];
  }
  try {
    const parsed = JSON.parse(whiteList);
    return Array.isArray(parsed) ? parsed : [];
  } catch (e) {
    // 如果不是JSON格式，尝试按逗号分隔
    return whiteList.split(',').map(ip => ip.trim()).filter(ip => ip.length > 0);
  }
}

// 加载配置列表
async function loadConfigList() {
  try {
    gridApi.setState({ gridOptions: { loading: true } });

    const data = await getConfigListApi(searchParams);

    // 响应拦截器已经将 MyBatis Plus 格式转换为标准格式
    // { records, total, current, size } -> { list, total, pageNum, pageSize }
    gridApi.setState({
      gridOptions: {
        data: data.list || [],
        loading: false,
        pagerConfig: {
          total: data.total || 0,
          currentPage: data.pageNum || 1,
          pageSize: data.pageSize || 10,
        },
      },
    });
  } catch (error) {
    console.error('加载配置列表失败:', error);
    message.error('加载配置列表失败');
    gridApi.setState({
      gridOptions: {
        data: [],
        loading: false,
      },
    });
  }
}

// 搜索
function handleSearch() {
  searchParams.pageNum = 1;
  loadConfigList();
}

// 重置
function handleReset() {
  searchParams.configName = undefined;
  searchParams.configType = undefined;
  searchParams.enabled = undefined;
  searchParams.pageNum = 1;
  searchParams.pageSize = 10;
  loadConfigList();
}

// 分页变化
function handlePageChange({ currentPage, pageSize }: any) {
  searchParams.pageNum = currentPage;
  searchParams.pageSize = pageSize;
  loadConfigList();
}

// 打开新增弹窗
function handleAdd() {
  isEdit.value = false;
  modalTitle.value = '新增配置';
  formData.value = {
    configName: '',
    configType: 'DEFAULT',
    limitType: 'GLOBAL',
    pathPattern: '',
    windowSeconds: 60,
    maxRequests: 100,
    enabled: true,
    whiteList: '',
    description: '',
  };
  modalVisible.value = true;
}

// 打开编辑弹窗
function handleEdit(row: RateLimitConfigEntity) {
  isEdit.value = true;
  modalTitle.value = '编辑配置';
  // 将JSON数组格式的whiteList转换为逗号分隔的字符串
  const editData = { ...row };
  if (editData.whiteList) {
    try {
      const whiteListArray = JSON.parse(editData.whiteList);
      editData.whiteList = Array.isArray(whiteListArray) ? whiteListArray.join(',') : editData.whiteList;
    } catch (e) {
      // 如果解析失败，保持原值
      console.warn('解析白名单失败:', e);
    }
  }
  formData.value = editData;
  modalVisible.value = true;
}

// 保存配置
async function handleSave() {
  try {
    // 准备提交的数据
    const submitData = { ...formData.value };

    // 将逗号分隔的字符串转换为JSON数组格式
    if (submitData.whiteList && submitData.whiteList.trim()) {
      const ipArray = submitData.whiteList
        .split(',')
        .map(ip => ip.trim())
        .filter(ip => ip.length > 0);
      submitData.whiteList = JSON.stringify(ipArray);
    } else {
      submitData.whiteList = '';
    }

    if (isEdit.value && submitData.id) {
      await updateConfigApi(submitData.id, submitData);
      message.success('更新成功');
    } else {
      await createConfigApi(submitData);
      message.success('创建成功');
    }
    modalVisible.value = false;
    await loadConfigList();
  } catch (error) {
    console.error('保存失败:', error);
    message.error('保存失败');
  }
}

// 删除配置
function handleDelete(row: RateLimitConfigEntity) {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除配置"${row.configName}"吗？`,
    okType: 'danger',
    onOk: async () => {
      try {
        if (row.id) {
          await deleteConfigApi(row.id);
          message.success('删除成功');
          await loadConfigList();
        }
      } catch (error) {
        console.error('删除失败:', error);
        message.error('删除失败');
      }
    },
  });
}

// 切换启用状态
async function handleToggleEnabled(row: RateLimitConfigEntity) {
  try {
    if (row.id) {
      await updateConfigEnabledApi(row.id, !row.enabled);
      message.success(row.enabled ? '已禁用' : '已启用');
      await loadConfigList();
    }
  } catch (error) {
    console.error('更新状态失败:', error);
    message.error('更新状态失败');
  }
}

// 刷新配置缓存
async function handleRefreshCache() {
  try {
    await refreshConfigApi();
    message.success('配置缓存已刷新');
  } catch (error) {
    console.error('刷新缓存失败:', error);
    message.error('刷新缓存失败');
  }
}

// 刷新列表
async function handleRefresh() {
  await loadConfigList();
}

// 表单验证规则
const formRules = {
  configName: [{ required: true, message: '请输入配置名称', trigger: 'blur' }],
  configType: [{ required: true, message: '请选择配置类型', trigger: 'change' }],
  pathPattern: [
    {
      required: computed(() => formData.value.configType === 'PATH'),
      message: '请输入路径模式',
      trigger: 'blur',
    },
  ],
  windowSeconds: [
    { required: true, message: '请输入时间窗口', trigger: 'blur' },
    { type: 'number', min: 1, message: '时间窗口必须大于0', trigger: 'blur' },
  ],
  maxRequests: [
    { required: true, message: '请输入最大请求数', trigger: 'blur' },
    { type: 'number', min: 1, message: '最大请求数必须大于0', trigger: 'blur' },
  ],
};

// 表单引用
const formRef = ref();

// 保存配置（带验证）
async function handleSaveWithValidation() {
  try {
    await formRef.value?.validate();
    await handleSave();
  } catch (error) {
    console.error('表单验证失败:', error);
  }
}

// 取消编辑
function handleCancel() {
  modalVisible.value = false;
  formRef.value?.resetFields();
}

// 页面挂载时加载数据
onMounted(() => {
  loadConfigList();
});
</script>

<template>
  <div class="flex h-full flex-col p-4">
    <!-- 搜索表单 -->
    <Card :bordered="false" class="mb-4 flex-shrink-0">
      <Space wrap>
        <Input
          v-model:value="searchParams.configName"
          placeholder="配置名称"
          allow-clear
          style="width: 200px"
          @press-enter="handleSearch"
        />
        <Select
          v-model:value="searchParams.configType"
          placeholder="配置类型"
          allow-clear
          style="width: 150px"
        >
          <SelectOption
            v-for="option in configTypeOptions"
            :key="option.value"
            :value="option.value"
          >
            {{ option.label }}
          </SelectOption>
        </Select>
        <Select
          v-model:value="searchParams.enabled"
          placeholder="启用状态"
          allow-clear
          style="width: 150px"
        >
          <SelectOption :value="true">启用</SelectOption>
          <SelectOption :value="false">禁用</SelectOption>
        </Select>
        <Button type="primary" @click="handleSearch">
          <template #icon><Search :size="16" /></template>
          查询
        </Button>
        <Button @click="handleReset">
          <template #icon><RefreshCw :size="16" /></template>
          重置
        </Button>
      </Space>
    </Card>

    <!-- 表格 -->
    <Card :bordered="false" class="flex flex-1 flex-col overflow-hidden">
      <div class="mb-4 flex flex-shrink-0 justify-between">
        <Space>
          <Button type="primary" @click="handleAdd">
            <template #icon>
              <Plus :size="16" />
            </template>
            新增配置
          </Button>
          <Button @click="handleRefreshCache">
            <template #icon>
              <Settings :size="16" />
            </template>
            刷新缓存
          </Button>
        </Space>
        <Tooltip title="刷新">
          <Button @click="handleRefresh">
            <RefreshCw :size="16" />
          </Button>
        </Tooltip>
      </div>

      <div class="flex-1 overflow-hidden">
        <Grid class="h-full" @page-change="handlePageChange">
        <!-- 配置类型列 -->
        <template #configType="{ row }">
          <Tag :color="getConfigTypeColor(row.configType)">
            {{ getConfigTypeText(row.configType) }}
          </Tag>
        </template>

        <!-- 限流类型列 -->
        <template #limitType="{ row }">
          <Tag v-if="row.limitType" :color="getLimitTypeColor(row.limitType)">
            {{ getLimitTypeText(row.limitType) }}
          </Tag>
          <span v-else class="text-gray-400">-</span>
        </template>

        <!-- 路径模式列 -->
        <template #pathPattern="{ row }">
          <Tooltip v-if="row.pathPattern" :title="row.pathPattern">
            <Tag color="cyan">{{ row.pathPattern }}</Tag>
          </Tooltip>
          <span v-else class="text-gray-400">-</span>
        </template>

        <!-- 状态列 -->
        <template #enabled="{ row }">
          <Tag :color="row.enabled ? 'success' : 'default'">
            <template #icon>
              <CheckCircle v-if="row.enabled" :size="14" />
              <XCircle v-else :size="14" />
            </template>
            {{ row.enabled ? '启用' : '禁用' }}
          </Tag>
        </template>

        <!-- IP白名单列 -->
        <template #whiteList="{ row }">
          <div v-if="row.whiteList && getWhiteListArray(row.whiteList).length > 0">
            <Tooltip>
              <template #title>
                <div v-for="(ip, index) in getWhiteListArray(row.whiteList)" :key="index">
                  {{ ip }}
                </div>
              </template>
              <Tag color="green">
                {{ getWhiteListArray(row.whiteList).length }} 个IP
              </Tag>
            </Tooltip>
          </div>
          <span v-else class="text-gray-400">-</span>
        </template>

        <!-- 操作列 -->
        <template #action="{ row }">
          <Space>
            <Switch
              :checked="row.enabled"
              size="small"
              @change="handleToggleEnabled(row)"
            />
            <Button size="small" type="link" @click="handleEdit(row)">
              <template #icon>
                <Edit :size="14" />
              </template>
              编辑
            </Button>
            <Button
              danger
              size="small"
              type="link"
              @click="handleDelete(row)"
            >
              <template #icon>
                <Trash2 :size="14" />
              </template>
              删除
            </Button>
          </Space>
        </template>
        </Grid>
      </div>
    </Card>

    <!-- 新增/编辑弹窗 -->
    <Modal
      v-model:open="modalVisible"
      :title="modalTitle"
      width="700px"
      @cancel="handleCancel"
      @ok="handleSaveWithValidation"
    >
      <Form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <FormItem label="配置名称" name="configName">
          <Input
            v-model:value="formData.configName"
            placeholder="请输入配置名称"
          />
        </FormItem>

        <FormItem label="配置类型" name="configType">
          <Select v-model:value="formData.configType" placeholder="请选择配置类型">
            <SelectOption
              v-for="option in configTypeOptions"
              :key="option.value"
              :value="option.value"
            >
              {{ option.label }}
            </SelectOption>
          </Select>
        </FormItem>

        <FormItem
          v-if="formData.configType === 'PATH'"
          label="路径模式"
          name="pathPattern"
        >
          <Input
            v-model:value="formData.pathPattern"
            placeholder="请输入路径模式，如：/api/user/**"
          />
        </FormItem>

        <FormItem
          v-if="formData.configType === 'PATH'"
          label="限流类型"
          name="limitType"
        >
          <RadioGroup v-model:value="formData.limitType">
            <Radio
              v-for="option in limitTypeOptions"
              :key="option.value"
              :value="option.value"
            >
              {{ option.label }}
            </Radio>
          </RadioGroup>
        </FormItem>

        <FormItem label="时间窗口(秒)" name="windowSeconds">
          <InputNumber
            v-model:value="formData.windowSeconds"
            :min="1"
            :max="86400"
            placeholder="请输入时间窗口"
            class="w-full"
          />
        </FormItem>

        <FormItem label="最大请求数" name="maxRequests">
          <InputNumber
            v-model:value="formData.maxRequests"
            :min="1"
            :max="1000000"
            placeholder="请输入最大请求数"
            class="w-full"
          />
        </FormItem>

        <FormItem label="启用状态" name="enabled">
          <Switch v-model:checked="formData.enabled" />
          <span class="ml-2 text-gray-500">
            {{ formData.enabled ? '启用' : '禁用' }}
          </span>
        </FormItem>

        <FormItem label="IP白名单" name="whiteList">
          <Textarea
            v-model:value="formData.whiteList"
            :rows="3"
            placeholder="请输入IP白名单，多个IP用逗号分隔，如：192.168.1.1,10.0.0.1"
          />
          <div class="mt-1 text-xs text-gray-500">
            白名单中的IP不受限流限制，多个IP用逗号分隔
          </div>
        </FormItem>

        <FormItem label="描述" name="description">
          <Textarea
            v-model:value="formData.description"
            :rows="3"
            placeholder="请输入配置描述"
          />
        </FormItem>
      </Form>
    </Modal>
  </div>
</template>

<style scoped>
/* 防止页面加载时的布局闪烁 */
:deep(.ant-card-body) {
  display: flex;
  flex-direction: column;
  height: 100%;
}
</style>

